use self::List::*;

enum List {
    Cons(u32, Box<List>),
    Nil,
}



impl List {
    fn new() -> List {
        Nil
    }

    fn prepend(self, x: u32 ) -> List {
        Cons(x, Box::new(self))
    }

    fn len(&self) -> u32{
        match self {
            Cons(_, tail) => tail.len() + 1,
            Nil => 0,
        }
    }
    fn stringify(&self) -> String {
        match self {
            Cons(node, tail) => format!("{}, {}", node, tail.stringify()),
            Nil => format!("Nil"),
        }
    }

    fn show(&self){
        match self {
            Cons(node, tail) => { 
                print!("{}, ",node);
                tail.show();
            }
            Nil => {
                println!("Nil");
            }
        }
    }
}


pub fn main(){
    let mut list = List::new();

    // list.prepend(1); => ????  fn prepend(&self, x: u32) { Cons( u32, Box::new(self???));}
    list = list.prepend(1);
    list = list.prepend(2); 
    list = list.prepend(3);

    println!("list len: {}", list.len());
    println!("list: {}", list.stringify());

    list.show();
}
